package com.koron.css2.systemManage.service;

import com.koron.common.web.bean.StaffBean;
import com.koron.css2.ApplicationConfig;
import com.koron.css2.serviceManage.bean.TWaterCompanyBean;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.serviceManage.bean.WaterCompanyListBean;
import com.koron.css2.serviceManage.mapper.TWaterCompanyMapper;
import com.koron.css2.serviceManage.utils.JsonUtils;
import com.koron.css2.serviceManage.utils.RedisUtils;
import com.koron.css2.systemManage.bean.OperationTreeBean;
import com.koron.css2.systemManage.bean.OrgUserBean;
import com.koron.css2.systemManage.bean.RoleBean;
import com.koron.css2.systemManage.bean.UserRangeBean;
import com.koron.css2.systemManage.dto.UserAuthorityDto;
import com.koron.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserService {
	
	private static Logger log = LogManager.getLogger(UserService.class);

	public UserAuthorityDto getUserAuthority(SessionFactory factory, UserInfoBean userInfo, String appId, String token) {
		String cache = RedisUtils.get("user_auth_" + token + "_" + userInfo.getUserInfo().getAcount());
		if(StringUtils.isNotBlank(cache)) {
			if(cache.contains("\\")) {  // 假如取出的对象中包含反斜杠
				cache = cache.substring(1, cache.length() - 1);
				cache = cache.replaceAll("\\\\", "");
			}
			return JsonUtils.jsonToPojo(cache, UserAuthorityDto.class);
		}
		UserAuthorityDto userAuthority = new UserAuthorityDto();
		try {
			boolean isAdmin = false;
			TWaterCompanyMapper mapper = factory.getMapper(TWaterCompanyMapper.class, "_default");
			OrgUserBean orgUser = new OrgUserBean();
			orgUser.setAccount(userInfo.getUserInfo().getAcount());
			orgUser.setCode(userInfo.getUserInfo().getCode());
			List<RoleBean> roles = ServiceFactory.getRoleService().listRoleByUser(orgUser, appId);
			if(roles == null || roles.size() == 0) {
				throw new UserAuthorityException("该账户未配置操作权限!!!");
			}
			List<List<OperationTreeBean>> operationList = new ArrayList<>();
			List<WaterCompanyListBean> companys = new ArrayList<WaterCompanyListBean>();
			for(RoleBean role : roles) {
				if(Constant.SUPER_ADMIN_NMAE.equals(role.getRoleName())) {
					isAdmin = true;
				}
			}
			if(isAdmin) {
				companys = mapper.selectTWaterCompanyList();
				companys = companys.stream().filter(t -> !t.getCompanyNo().equals(ApplicationConfig.getWaterCodeFilter())).collect(Collectors.toList());
				StaffBean staff = Tools.getStaffBean(userInfo.getUserInfo().getAcount()); // 从公共库中查找 账户信息
				if (staff == null){
					throw new UserAuthorityException("系统中未找到" + userInfo.getUserInfo().getAcount() + "账户信息");
				}
				userAuthority.setUserName(staff.getName());
			} else {
				List<UserRangeBean> userRanges = ServiceFactory.getDataRangeService().getUserRangeValueList(userInfo.getUserInfo().getCode(), appId, "company");
				if(userRanges.size() == 0) {
					throw new UserAuthorityException("该账户未配置数据查看权限!!!");
				}
				if(userRanges != null) {
					List<String> list = userRanges.stream().map(t -> t.getValue()).collect(Collectors.toList());
					List<TWaterCompanyBean> waterCompanys = mapper.selectTWaterCompanyByCodeList(list);
					companys = waterCompanys.stream().map(t -> new WaterCompanyListBean(t.getCompanyNo(), t.getShortName(), t.getDomain())).collect(Collectors.toList());
				}
				orgUser = Tools.getOrgUserByAccount(DBSourceUtils.getDbEnv(companys.get(0).getCompanyNo()), userInfo.getUserInfo().getAcount()); // 从水司库中查找账户信息
				if (orgUser == null){
					throw new UserAuthorityException("系统中未找到" + userInfo.getUserInfo().getAcount() + "账户信息");
				}
				if(orgUser.getStatus() == 1){
					throw new UserAuthorityException("该账号" + orgUser.getAccount() + "已停用");
				}
				userAuthority.setUserName(orgUser.getUserName());
			}
			if(StringUtils.isEmpty(userInfo.getCurWaterCode())){
				userInfo.setCurWaterCode(companys.get(0).getCompanyNo());
			}
			for(RoleBean role : roles) {
				List<OperationTreeBean> operations = ServiceFactory.getOperationService().listOPByRole(appId, userInfo, role.getRoleCode(), false);
				if(operations != null && operations.size() > 0) {
					operationList.add(operations);
				}
			}
			if(operationList.size() == 0) {
				throw new UserAuthorityException("该账户未配置操作权限!!!");
			}
			for (List<OperationTreeBean> list : operationList) {
				for (OperationTreeBean op : list) {
					if (StringUtils.isNotBlank(op.getUrl())) {
						op.setUrl(op.getUrl().replaceAll("#", ""));
					}
				}
			}
			// 转成List
			List<OperationTreeBean> allOperationTree = new ArrayList<>();

			// 取并集重复的不添加
			for(List<OperationTreeBean> data : operationList) {
				for(OperationTreeBean operation : data) {
					if(!allOperationTree.contains(operation)) {
						allOperationTree.add(operation);
					}
				}
			}

			Collections.sort(allOperationTree, Comparator.nullsFirst(Comparator.comparing(OperationTreeBean::getOpWeight)));

			String currentCompany = RedisUtils.get("user_company_" + token + "_" + userInfo.getUserInfo().getAcount());
			if (StringUtils.isEmpty(currentCompany)){
				currentCompany = companys.get(0).getCompanyNo();
			}

			for (WaterCompanyListBean company : companys){
				if (Objects.equals(company.getCompanyNo(), currentCompany)){
					userAuthority.setDomain(company.getDomain());
				}
			}

			// 组织成树形结构
			Collections.sort(allOperationTree, Comparator.nullsFirst(Comparator.comparing(OperationTreeBean::getOpWeight)));

			// 组织成树形结构
			List<OperationTreeBean> finalOperation = TreeUtils.list2TreeList(allOperationTree, "opCode", "parentOpCode", "children");

			userAuthority.setCurWaterCode(currentCompany);
			userAuthority.setRoles(roles);
			userAuthority.setAccount(userInfo.getUserInfo().getAcount());
			userAuthority.setOperations(finalOperation);
			userAuthority.setCompanys(companys);
			userAuthority.setDomain("");
			RedisUtils.setEx("user_auth_" + token + "_" + userInfo.getUserInfo().getAcount(), ApplicationConfig.getExpireTime(), JsonUtils.objectToJson(userAuthority));
			RedisUtils.setEx("user_company_" + token + "_" + userInfo.getUserInfo().getAcount(), ApplicationConfig.getExpireTime(), companys.get(0).getCompanyNo());
		}catch (Exception exception){
			exception.printStackTrace();
		}
		return userAuthority;
	}
}
